{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9b5826dfda9c2f04",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# Using QingYan GLMs To OpenAI API\n",
    "\n",
    "**This tutorial is available in English and is attached below the Chinese explanation**\n",
    "\n",
    "本教程指导您使用[GLMs API转OpenAI接口的网关](https://github.com/LLM-Red-Team/zhipuai-agent-to-openai)，旨在降低开发者们接入[智能体API](https://zhipu-ai.feishu.cn/wiki/X8ykw4IXpieCOxkYxbrcxT9vn5f)的门槛。\n",
    "\n",
    "This tutorial guides you through using the [gateway converting GLMs API to OpenAI interface](https://github.com/LLM-Red-Team/zhipuai-agent-to-openai), designed to lower the barrier for developers to access the [Agent API](https://zhipu-ai.feishu.cn/wiki/X8ykw4IXpieCOxkYxbrcxT9vn5f).\n",
    "\n",
    "<span style='color: red; font-weight: bold;'>⚠️ 目前，您只能调用属于自己的智能体，不能调用别人的智能体！ ⚠️</span>\n",
    "\n",
    "<span style='color: red; font-weight: bold;'>⚠️ Currently, you can only call your own GLMs Agent, not other people's ! ⚠️</span>\n",
    "\n",
    "# 1. 获取API Key\n",
    "\n",
    "前往智谱清言智能体[创作者中心](https://chatglm.cn/developersPanel/apiSet)创建API Key，并使用`.`拼接Key与Secret为API Key，如下所示：\n",
    "\n",
    "Go to the Zhipu Qingyan Agent [Creator Center](https://chatglm.cn/developersPanel/apiSet) to create an API Key, and concatenate the Key and Secret with `.` to form the API Key, as shown below:\n",
    "\n",
    "```\n",
    "21a**********9a0.2fa****************************237\n",
    "```\n",
    "\n",
    "# 2. 部署\n",
    "\n",
    "## Docker部署\n",
    "\n",
    "请准备一台具有公网IP的服务器并将8000端口开放。\n",
    "\n",
    "Please prepare a server with a public IP address and open port 8000.\n",
    "\n",
    "拉取镜像并启动服务\n",
    "\n",
    "Pull the image and start the service\n",
    "\n",
    "```shell\n",
    "docker run -it -d --init --name zhipuai-agent-to-openai -p 8000:8000 -e TZ=Asia/Shanghai vinlic/zhipuai-agent-to-openai:latest\n",
    "```\n",
    "\n",
    "查看服务实时日志\n",
    "\n",
    "View service logs in real-time\n",
    "\n",
    "```shell\n",
    "docker logs -f zhipuai-agent-to-openai\n",
    "```\n",
    "\n",
    "重启服务\n",
    "\n",
    "Restart the service\n",
    "\n",
    "```shell\n",
    "docker restart zhipuai-agent-to-openai\n",
    "```\n",
    "\n",
    "停止服务\n",
    "\n",
    "Stop the service\n",
    "\n",
    "```shell\n",
    "docker stop zhipuai-agent-to-openai\n",
    "```\n",
    "\n",
    "### Docker-compose 部署\n",
    "\n",
    "```yaml\n",
    "version: '3'\n",
    "services:\n",
    "  zhipuai-agent-to-openai:\n",
    "    container_name: zhipuai-agent-to-openai\n",
    "    image: vinlic/zhipuai-agent-to-openai:latest\n",
    "    restart: always\n",
    "    ports:\n",
    "      - \"8000:8000\"\n",
    "    environment:\n",
    "      - TZ=Asia/Shanghai\n",
    "```\n",
    "\n",
    "## 原生部署\n",
    "\n",
    "请准备一台具有公网IP的服务器并将8000端口开放。\n",
    "\n",
    "Please prepare a server with a public IP address and open port 8000.\n",
    "\n",
    "请先安装好Node.js环境并且配置好环境变量，确认node命令可用。\n",
    "\n",
    "First, install Node.js and configure the environment variables to ensure the `node` command is available.\n",
    "\n",
    "安装依赖\n",
    "\n",
    "Install dependencies\n",
    "\n",
    "```shell\n",
    "npm i\n",
    "```\n",
    "\n",
    "安装PM2进行进程守护\n",
    "\n",
    "Install PM2 for process management\n",
    "\n",
    "```shell\n",
    "npm i -g pm2\n",
    "```\n",
    "\n",
    "编译构建，看到dist目录就是构建完成\n",
    "\n",
    "Compile and build, once the `dist` directory is seen, the build is complete\n",
    "\n",
    "```shell\n",
    "npm run build\n",
    "```\n",
    "\n",
    "启动服务\n",
    "\n",
    "Start the service\n",
    "\n",
    "```shell\n",
    "pm2 start dist/index.js --name \"zhipuai-agent-to-openai\"\n",
    "```\n",
    "\n",
    "查看服务实时日志\n",
    "\n",
    "View service logs in real-time\n",
    "\n",
    "```shell\n",
    "pm2 logs zhipuai-agent-to-openai\n",
    "```\n",
    "\n",
    "重启服务\n",
    "\n",
    "Restart the service\n",
    "\n",
    "```shell\n",
    "pm2 reload zhipuai-agent-to-openai\n",
    "```\n",
    "\n",
    "停止服务\n",
    "\n",
    "Stop the service\n",
    "\n",
    "```shell\n",
    "pm2 stop zhipuai-agent-to-openai\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3deb1647a5b275e",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 2. 接入智能体能力\n",
    "\n",
    "## 对话补全\n",
    "\n",
    "对话补全接口，与openai的 [chat-completions-api](https://platform.openai.com/docs/guides/text-generation/chat-completions-api) 兼容。\n",
    "\n",
    "**POST /v1/chat/completions**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "23e9879d7206cdff",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-09T08:51:03.267827Z",
     "start_time": "2024-05-09T08:51:03.260223Z"
    },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好，地球人。\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from openai import OpenAI\n",
    "\n",
    "# 在环境变量中设置OPENAI_API_BASE为您部署的zhipuai-agent-to-openai服务地址\n",
    "BASE_URL = os.getenv(\"OPENAI_API_BASE\", \"http://127.0.0.1:8000/v1\")\n",
    "# 在环境变量中设置OPENAI_API_KEY为第一步拼接获得的API Key或者直接填写\n",
    "API_KEY = os.getenv(\"OPENAI_API_KEY\", \"21a**********9a0.2fa****************************237\")\n",
    "\n",
    "client = OpenAI(\n",
    "    base_url=BASE_URL,\n",
    "    api_key=API_KEY\n",
    ")\n",
    "\n",
    "# 调用对话补全接口\n",
    "result = client.chat.completions.create(\n",
    "    # 必须填写您自己创建的智能体ID，否则无法调用成功\n",
    "    model=\"65d6ba38fca9900836172419\",\n",
    "    # 目前多轮对话基于消息合并实现，某些场景可能导致能力下降且受单轮最大token数限制\n",
    "    # 如果您想获得原生的多轮对话体验，可以传入首轮消息获得的id，来接续上下文\n",
    "    # \"conversation_id\": \"65f6c28546bae1f0fbb532de\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"你好\"\n",
    "        }\n",
    "    ],\n",
    "    # 如果使用SSE流请设置为true，默认false\n",
    "    stream=False\n",
    ")\n",
    "\n",
    "# 输出调用结果\n",
    "print(result.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0426035",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "## AI绘图\n",
    "\n",
    "对话补全接口，与openai的 [images-create-api](https://platform.openai.com/docs/api-reference/images/create) 兼容。\n",
    "\n",
    "**POST /v1/images/generations**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "01b48cdc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "https://sfile.chatglm.cn/testpath/c554098d-3aeb-5d12-a9f1-24eeda54a3ef_0.png\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from openai import OpenAI\n",
    "\n",
    "# 在环境变量中设置OPENAI_API_BASE为您部署的zhipuai-agent-to-openai服务地址\n",
    "BASE_URL = os.getenv(\"OPENAI_API_BASE\", \"http://127.0.0.1:8000/v1\")\n",
    "# 在环境变量中设置OPENAI_API_KEY为第一步拼接获得的API Key或者直接填写\n",
    "API_KEY = os.getenv(\"OPENAI_API_KEY\", \"21a**********9a0.2fa****************************237\")\n",
    "\n",
    "client = OpenAI(\n",
    "    base_url=BASE_URL,\n",
    "    api_key=API_KEY\n",
    ")\n",
    "\n",
    "# 调用对话补全接口\n",
    "result = client.images.generate(\n",
    "    # 必须填写您自己创建的智能体ID，否则无法调用成功\n",
    "    model=\"65d6ba38fca9900836172419\",\n",
    "    prompt=\"一只猫\"\n",
    ")\n",
    "\n",
    "# 输出调用结果\n",
    "print(result.data[0].url)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "daa264c5",
   "metadata": {},
   "source": [
    "## 文档解读\n",
    "\n",
    "提供一个可访问的文件URL或者BASE64_URL进行解析。\n",
    "\n",
    "**POST /v1/chat/completions**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "443f639f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "STM32F405xx 和 STM32F407xx 是基于 Arm Cortex-M4 内核的高性能微控制器，具有 168MHz 的处理速度。它们包含高达 192KB 的 SRAM、512KB 到 1MB 的 Flash 存储器，以及丰富的外设，如 3 个 12 位 ADC、2 个 12 位 DAC、1 个低功耗 RTC 和 12 个通用 16 位定时器。此外，STM32F407xx 还包括一个相机接口和以太网接口。这些微控制器支持多种低功耗模式，工作电压范围为 1.8V 至 3.6V。\n",
      "\n",
      "该文档提供了 STM32F405xx 和 STM32F407xx 微控制器的详细技术规格，包括功能描述、引脚定义、内存映射、电气特性、封装信息等。这些信息旨在帮助用户了解 STM32F405xx 和 STM32F407xx 的特性和应用，以便在设计和开发过程中做出明智的决策。\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from openai import OpenAI\n",
    "\n",
    "# 在环境变量中设置OPENAI_API_BASE为您部署的zhipuai-agent-to-openai服务地址\n",
    "BASE_URL = os.getenv(\"OPENAI_API_BASE\", \"http://127.0.0.1:8000/v1\")\n",
    "# 在环境变量中设置OPENAI_API_KEY为第一步拼接获得的API Key或者直接填写\n",
    "API_KEY = os.getenv(\"OPENAI_API_KEY\", \"21a**********9a0.2fa****************************237\")\n",
    "\n",
    "client = OpenAI(\n",
    "    base_url=BASE_URL,\n",
    "    api_key=API_KEY\n",
    ")\n",
    "\n",
    "# 调用对话补全接口\n",
    "result = client.chat.completions.create(\n",
    "    # 必须填写您自己创建的智能体ID，否则无法调用成功\n",
    "    model=\"65d6ba38fca9900836172419\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": [\n",
    "                {\n",
    "                    \"type\": \"file\",\n",
    "                    \"file_url\": {\n",
    "                        \"url\": \"https://sfile.chatglm.cn/chatglm4/d9c5a4b6-f2cf-4564-aadd-892cfd4bb835.pdf\"\n",
    "                    }\n",
    "                },\n",
    "                {\n",
    "                    \"type\": \"text\",\n",
    "                    \"text\": \"文档说了什么？\"\n",
    "                }\n",
    "            ]\n",
    "        }\n",
    "    ],\n",
    "    # 如果使用SSE流请设置为true，默认false\n",
    "    stream=False\n",
    ")\n",
    "\n",
    "# 输出调用结果\n",
    "print(result.choices[0].message.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7588448d",
   "metadata": {},
   "source": [
    "### 图像解析\n",
    "\n",
    "提供一个可访问的图像URL或者BASE64_URL进行解析。\n",
    "\n",
    "此格式兼容 [gpt-4-vision-preview](https://platform.openai.com/docs/guides/vision) API格式，您也可以用这个格式传送文档进行解析。\n",
    "\n",
    "**POST /v1/chat/completions**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "13c4abfc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "图中是一张电影海报，具体信息如下：\n",
      "- **电影名称**：《你的名字》\n",
      "- **英文名**：your name.\n",
      "- **导演**：新海诚\n",
      "- **编剧**：神木隆之介\n",
      "- **配音演员**：上白石萌音\n",
      "- **音乐**：RADWIMPS乐队\n",
      "- **上映日期**：12月2日\n",
      "- **宣传语**：“一起看吧”\n",
      "\n",
      "该电影是日本年度票房总冠军，由北京光线影业有限公司协助推广，中国电影股份有限公司进口，华夏电影发行有限责任公司发行。海报展示了两位主角站在城市和乡村的交界处，背景是蓝天白云和流星划过的场景。\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from openai import OpenAI\n",
    "\n",
    "# 在环境变量中设置OPENAI_API_BASE为您部署的zhipuai-agent-to-openai服务地址\n",
    "BASE_URL = os.getenv(\"OPENAI_API_BASE\", \"http://127.0.0.1:8000/v1\")\n",
    "# 在环境变量中设置OPENAI_API_KEY为第一步拼接获得的API Key或者直接填写\n",
    "API_KEY = os.getenv(\"OPENAI_API_KEY\", \"21a**********9a0.2fa****************************237\")\n",
    "\n",
    "client = OpenAI(\n",
    "    base_url=BASE_URL,\n",
    "    api_key=API_KEY\n",
    ")\n",
    "\n",
    "# 调用对话补全接口\n",
    "result = client.chat.completions.create(\n",
    "    # 必须填写您自己创建的智能体ID，否则无法调用成功\n",
    "    model=\"65d6ba38fca9900836172419\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": [\n",
    "                {\n",
    "                    \"type\": \"file\",\n",
    "                    \"file_url\": {\n",
    "                        \"url\": \"https://sfile.chatglm.cn/chatglm4/0d507d4e-4a08-40d5-b691-417c47cc8aa3.png\"\n",
    "                    }\n",
    "                },\n",
    "                {\n",
    "                    \"type\": \"text\",\n",
    "                    \"text\": \"图里是啥？\"\n",
    "                }\n",
    "            ]\n",
    "        }\n",
    "    ],\n",
    "    # 如果使用SSE流请设置为true，默认false\n",
    "    stream=False\n",
    ")\n",
    "\n",
    "# 输出调用结果\n",
    "print(result.choices[0].message.content)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
